package com.ytq.secutiry.config;

import com.ytq.secutiry.config.filter.ImageVerificationFilter;
import com.ytq.secutiry.config.filter.JwtFilter;
import com.ytq.secutiry.config.handler.FailureHandlerRequest;
import com.ytq.secutiry.config.handler.SuccessHandlerRequest;
import com.ytq.secutiry.service.UserDetailServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.access.AccessDeniedHandlerImpl;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

/**
 * @author yuantongqin
 * desc:
 * 2020-09-29
 */
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    UserDetailServiceImpl userDetailService;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//        super.configure(auth);
        auth.userDetailsService(userDetailService).passwordEncoder(new BCryptPasswordEncoder());
    }

    /**
     * 保证创建出 AuthenticationManager Bean 。
     *
     * @return
     * @throws Exception
     */

    @Autowired
    SuccessHandlerRequest successHandlerRequest;
    @Autowired
    FailureHandlerRequest failureHandlerRequest;
    @Autowired
    ImageVerificationFilter filter;


    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //super.configure(http);
        // 所有的请求都需要验证
        http
                // CRSF禁用，因为不使用session,如果不去掉会一直出错
                .csrf().disable()
                // 基于token，所以不需要session
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .authorizeRequests()
                // 允许对于网站静态资源的无授权访问
                .antMatchers(HttpMethod.GET,
                        "/",
                        "/*.html",
                        "/favicon.ico",
                        "/**/*.html",
                        "/**/*.css",
                        "/**/*.js",
                        "/swagger-resources/**",
                        "/v2/api-docs/**"
                )
                .permitAll()
                .and()
                // 只有ytq/login接口才会做用户名与密码验证filter
                    .formLogin().loginPage("/formLogin")
                    // 处理登录请求的接口
                    .loginProcessingUrl("/ytq/login")
                    // 运行通过，不需要验证
                    .permitAll()

                    .successHandler(successHandlerRequest)
                    .failureHandler(failureHandlerRequest)
                .and().headers().frameOptions().disable()
                .and().authorizeRequests().anyRequest().authenticated()
                .and().logout().permitAll()
                .and()
                    .exceptionHandling()
                    .accessDeniedHandler(new AccessDeniedHandlerImpl())
                // 所有的接口都会走addFilter的过滤器，所以在filter中要判断请求路径
        .and().addFilterBefore(filter, UsernamePasswordAuthenticationFilter.class)
                .addFilter(new JwtFilter(authenticationManager()));

    }
}
